﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
using System.Web;
using System.Xml;
using System.Xml.Serialization;
using Universe.MediaProbe;
using Universe.MediaProbe.Utils;

namespace MediaProbe.W3Test
{
    public class SampleVideo
    {
        static private byte[] NativeReport;
        public static readonly string SampleUrl = "~/VideoSample/Vintage Columbia 1959.mp4";
        private static readonly object Sync = new object();
        private static byte[] Screen;

        public static string AbsolutePath
        {
            get
            {
                return HttpContext.Current.Server.MapPath(SampleUrl);
            }
        }

        public static ProbeReport BuildProbeReport()
        {
            byte[] probeBytes = BuildNativeReport();
            var report = ProbeReportParser.Parse(probeBytes);
            report.FullName = AbsolutePath;
            return report;
        }

        public static Lazy<string> ProbeReportAsHtml = new Lazy<string>(delegate
        {
            var report = SampleVideo.BuildProbeReport();
            XmlSerializer xs = new XmlSerializer(typeof(ProbeReport));
            string html;
            using (MemoryStream mem = new MemoryStream())
            {
                XmlTextWriter wr = new XmlTextWriter(mem, Encoding.UTF8);
                wr.Formatting = Formatting.Indented;
                xs.Serialize(wr, report);
                html = XmlUtils.GetXmlAsHtml(mem.ToArray());
            }

            return html;

        }, LazyThreadSafetyMode.ExecutionAndPublication); 

        public static Lazy<string> NativeReportAsHtml = new Lazy<string>(delegate
        {
            byte[] probeBytes = SampleVideo.BuildNativeReport();
            Encoding utf8 = new UTF8Encoding(false);
            XmlDocument doc = null;
            Exception exParse = null;
            if (!XmlUtils.SafeLoad(probeBytes, utf8, out doc, out exParse))
            {
                throw new InvalidOperationException(
                    "ffprobe valid xml report is expacted. Probably ffprobe is not supported by operation system. Please report to dev",
                    exParse);
            }

            var doc2 = new MemoryStream();
            doc.Save(doc2);
            doc2.Position = 0;
            XmlTextReader tr = new XmlTextReader(doc2);


            var ret = XmlUtils.GetXmlAsHtml(tr);
            return ret;
        }, LazyThreadSafetyMode.ExecutionAndPublication);

        public static byte[] BuildNativeReport()
        {
            lock(Sync)
                if (NativeReport == null)
                    NativeReport = ProbeReportBuilder.BuildRawProbe(AbsolutePath);

            return NativeReport;
        }

        public static void BuildScreen(out byte[] content, out string contentType)
        {
            lock (Sync)
                if (Screen == null)
                {
                    var report = SampleVideo.BuildProbeReport();
                    ScreenGrabber gr = new ScreenGrabber(report)
                    {
                        OutFormat = ScreenGrabber.OutputFormat.JpegBest,
                        OutSize = new ScreenGrabber.OutputSize() { OptionalHeight = 190 }
                    };

                    using (ScreenGrabber.Screen screen = gr.Grab1Frame(5.0m))
                    {
                        MemoryStream mem = new MemoryStream();
                        screen.CopyTo(mem);
                        Screen = mem.ToArray();
                    }
                }

            content = Screen;
            contentType = "image/jpeg";
        }

    }
}